#ifndef CLIENT_HPP
#define CLIENT_HPP

#include <QObject>
#include <QTcpSocket>
#include <QString>
#include <QVector>
#include <QPair>

#include "../../src/idmanager.hpp"
#include "reseau.hpp"
#include "game.hpp"

class Reseau;
class Game;

class Client : public QObject
{
    Q_OBJECT

public:
    Client(QTcpSocket * socket, const Reseau * reseau, QObject * parent = 0);
    ~Client();

    const QString & name();
    const QTcpSocket * socket();

    bool isConnected();

private:
    QTcpSocket * _socket;
    QString _name;
    QByteArray * _paquet;
    QDataStream * _in;
    QDataStream * _out;
    quint16 _messageSize;
    bool _connected;
    const Reseau * _reseau;

private:
    void prePaquet();
    void postPaquet();
    void writeStamp(Mid::MessageID mid);
    void dispatch(Mid::MessageID mid);

    bool fileExists(const QString & name);
    void fileAdd(const QString & name, const QString & pw);
    bool fileCheck(const QString & name, const QString & pw);

    bool areValid(const QString & name, QString & pw);

public slots:
    void send(Mid::MessageID mid);
    void send(Mid::MessageID mid, quint8 i0);
    void send(Mid::MessageID mid, quint8 i0, qreal r0);
    void send(Mid::MessageID mid, quint8 i0, const QString & s0);
    void send(Mid::MessageID mid, quint8 i0, const QString & s0, const QString & s1);
    void send(Mid::MessageID mid, quint8 i0, quint8 i1);
    void send(Mid::MessageID mid, quint8 i0, quint8 i1, quint8 i2);
    void send(Mid::MessageID mid, quint8 i0, quint8 i1, quint8 i2, quint8 i3);
    void send(Mid::MessageID mid, quint8 i0, quint8 i1, qreal r0);
    void send(Mid::MessageID mid, quint8 i0, quint8 i1, qreal r0, const QString & s0);
    void send(Mid::MessageID mid, quint8 i0, quint8 i1, const QString & s0);
    void send(Mid::MessageID mid, quint8 i0, const QStringList & s0);
    void send(Mid::MessageID mid, const QString & s0);
    void send(Mid::MessageID mid, const QString & s0, const QString & s1);
    void send(Mid::MessageID mid, const QStringList & s0);
    void send(Mid::MessageID mid, const QList<Game *> & l0);
    void send(Mid::MessageID mid, const Game & g);

    void disconnect();

private slots:
    //! Appelée dès qu'on reçoit des données par la socket
    void donneesRecues();
    void deconnexion();

    void reactInscription(const QString & pseudo, QString & mdp);
    void reactConnection(const QString & pseudo, QString & mdp);

signals:
    void NTinscription(const QString & pseudo, QString & mdp);
    void NTconnection(const QString & pseudo, QString & mdp);
    void NTcreateGame(quint8 gobanSize, qreal komi);
    void NTwantToPlay(quint8 idPartie);
    void NTwantToSee(quint8 idPartie);
    void NTgameQuit(quint8 idPartie);
    void NTgameDestroy(quint8 idPartie);
    void NTplayMove(quint8 idPartie, quint8 x,quint8 y);
    void NTskipTurn(quint8 idPartie);
    void NTdeadGroup(quint8 idPartie, quint8 x,quint8 y);
    void NTaliveGroup(quint8 idPartie, quint8 x,quint8 y);
    void NTvalidateGroups(quint8 idPartie);
    void NTlobbySay(const QString & message);
    void NTgameSay(quint8 idPartie, const QString & message);
    void NTdontWantToSeeAnymore(quint8 idPartie);
    void NTtoPlay(quint8 idPartie);

    void deconnexion(const QString & name);
    void identified(const QString & name);
};

#endif // CLIENT_HPP
